home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_08
/
1008038a
< prev
next >
Wrap
Text File
|
1992-05-28
|
17KB
|
422 lines
/* RAY_RAD - A Very Simple Ray-Traced Radiosity Renderer */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define FLOOR 0 /* X-Y plane, Z = 0.0 */
#define SOUTH_WALL 1 /* X-Z plane, Y = 0.0 */
#define EAST_WALL 2 /* Y-Z plane, X = 8.0 */
#define NORTH_WALL 3 /* X-Z plane, Y = 8.0 */
#define WEST_WALL 4 /* X-Z plane, X = 0.0 */
#define MAX_RAYS 25000 /* Maximum number of rays */
#define MAX_VAL 1.0e+6 /* Maximum floating point value */
#define MIN_VAL 1.0e-6 /* Minimum floating point value */
#define NUM_LOOP 20 /* Number of iterations */
#define NUM_SURF 10 /* Number of surfaces */
#define PI 3.141592654
#define DRAND() ((double) rand() / (double) RAND_MAX)
typedef struct /* 3-D point co-ordinates */
{
double x; /* X-axis co-ordinate */
double y; /* Y-axis co-ordinate */
double z; /* Z-axis co-ordinate */
} PT_3D;
typedef struct /* 3-D ray */
{
PT_3D org; /* Origin */
PT_3D dir; /* Direction */
} RAY;
typedef struct /* Element */
{
double total; /* Total flux */
double unsent; /* Unsent flux */
} ELEM;
typedef struct /* Surface */
{
PT_3D vertex[4]; /* Vertex array */
int num_row; /* Number of element rows */
int num_col; /* Number of element columns */
double col_dim; /* Element column dimension */
double row_dim; /* Element row dimension */
double emittance; /* Emittance */
double reflectance; /* Reflectance */
ELEM *elemp; /* Element array pointer */
} SURF;
static int send_flux(int, int, int);
static void display_surface(void);
static void find_element(RAY *, int *, int *, int *);
static void global_to_local(int, PT_3D *, PT_3D *);
static void local_to_global(int, RAY *, RAY *);
static void select_ray(int, int, int, RAY *);
static double MaxEmittance = 0.0; /* Maximum emittance */
static SURF RoomSurf[NUM_SURF] = { /* Room surfaces */
{ { { 0.0, 0.0, 0.0 }, { 8.0, 0.0, 0.0 }, /* Floor */
{ 8.0, 8.0, 0.0 }, { 0.0, 8.0, 0.0 } }, 8, 8, 1.0, 1.0,
0.0, 0.2, NULL },
{ { { 0.0, 0.0, 0.0 }, { 0.0, 0.0, 8.0 }, /* South wall */
{ 8.0, 0.0, 8.0 }, { 8.0, 0.0, 0.0 } }, 8, 8, 1.0, 1.0,
0.0, 0.5, NULL },
{ { { 8.0, 0.0, 0.0 }, { 8.0, 0.0, 8.0 }, /* East wall */
{ 8.0, 8.0, 8.0 }, { 8.0, 8.0, 0.0 } }, 8, 8, 1.0, 1.0,
0.0, 0.5, NULL },
{ { { 8.0, 8.0, 0.0 }, { 8.0, 8.0, 8.0 }, /* North wall */
{ 0.0, 8.0, 8.0 }, { 0.0, 8.0, 0.0 } }, 8, 8, 1.0, 1.0,
0.0, 0.5, NULL },
{ { { 0.0, 8.0, 0.0 }, { 0.0, 8.0, 8.0 }, /* West wall */
{ 0.0, 0.0, 8.0 }, { 0.0, 0.0, 0.0 } }, 8, 8, 1.0, 1.0,
0.0, 0.5, NULL },
{ { { 0.0, 0.0, 8.0 }, { 0.0, 3.0, 8.0 }, /* South ceil. */
{ 8.0, 3.0, 8.0 }, { 8.0, 0.0, 8.0 } }, 8, 3, 1.0, 1.0,
0.0, 0.8, NULL },
{ { { 5.0, 3.0, 8.0 }, { 5.0, 5.0, 8.0 }, /* East ceiling */
{ 8.0, 5.0, 8.0 }, { 8.0, 3.0, 8.0 } }, 3, 2, 1.0, 1.0,
0.0, 0.8, NULL },
{ { { 0.0, 5.0, 8.0 }, { 0.0, 8.0, 8.0 }, /* North ceil. */
{ 8.0, 8.0, 8.0 }, { 8.0, 5.0, 8.0 } }, 8, 3, 1.0, 1.0,
0.0, 0.8, NULL },
{ { { 0.0, 3.0, 8.0 }, { 0.0, 5.0, 8.0 }, /* West ceiling */
{ 3.0, 5.0, 8.0 }, { 3.0, 3.0, 8.0 } }, 3, 2, 1.0, 1.0,
0.0, 0.8, NULL },
{ { { 3.0, 3.0, 8.0 }, { 3.0, 5.0, 8.0 }, /* Ceil. light */
{ 5.0, 5.0, 8.0 }, { 5.0, 3.0, 8.0 } }, 2, 2, 1.0, 1.0,
5000.0, 0.8, NULL } };
int main(void)
{
int col; /* Column counter */
int elem; /* Element counter */
int maximum; /* Maximum number of rays */
int num_elem; /* Number of elements */
int num_rays; /* Number of rays */
int row; /* Row counter */
int surf; /* Surface counter */
ELEM *elemp; /* Element pointer */
SURF *surfp; /* Surface pointer */
for (surf = 0; surf < NUM_SURF; surf++) {
/* Instantiate elements */
surfp = &(RoomSurf[surf]);
num_elem = surfp->num_row * surfp->num_col;
if ((surfp->elemp = (ELEM *) malloc(num_elem * sizeof(ELEM)))
== NULL) {
fputs("Out of memory!\n", stderr);
return (2);
}
elemp = surfp->elemp;
for (elem = 0; elem < num_elem; elem++, elemp++)
elemp->total = elemp->unsent = surfp->emittance;
if (surfp->emittance > MaxEmittance)
MaxEmittance = surfp->emittance;
}
do {
/* Distribute flux between elements */
num_rays = 0;
for (surf = 0; surf < NUM_SURF; surf++) {
surfp = &(RoomSurf[surf]);
for (row = 0; row < surfp->num_row; row++)
for (col = 0; col < surfp->num_col; col++) {
if ((maximum = send_flux(surf, row, col)) > num_rays)
num_rays = maximum;
}
}
display_surface(); /* Display intermediate results */
} while (num_rays > 0); /* Repeat until convergence */
for (surf = 0; surf < NUM_SURF; surf++) /* Free memory */
free(RoomSurf[surf].elemp);
return (0);
}
static int send_flux ( /* Send flux to other elements */
int s_surf, /* Sending surface index */
int s_row, /* Sending element row */
int s_col ) /* Sending element column */
{
int h_col; /* Hit element column */
int h_row; /* Hit element row */
int h_surf; /* Hit surface index */
int num_rays; /* Number of rays */
int ray; /* Ray counter */
double inc_flux; /* Incident (ray) flux */
double ref_flux; /* Reflected flux */
RAY shoot; /* Shooting ray */
ELEM *h_elemp; /* Hit element pointer */
ELEM *s_elemp; /* Sending element pointer */
SURF *h_surfp; /* Hit surface pointer */
SURF *s_surfp; /* Sending surface pointer */
s_surfp = &(RoomSurf[s_surf]);
s_elemp = s_surfp->elemp + s_row * s_surfp->num_col + s_col;
/* Number of rays to shoot proportional to unsent flux */
if ((num_rays = (int) (MAX_RAYS * s_elemp->unsent /
MaxEmittance)) == 0)
return (0);
inc_flux = s_elemp->unsent / num_rays; /* Get ray flux */
for (ray = 0; ray < num_rays; ray++) { /* Distribute flux */
select_ray(s_surf, s_row, s_col, &shoot); /* Select ray */
/* Find hit surface and element */
find_element(&shoot, &h_surf, &h_row, &h_col);
/* Calculate flux reflected from hit element */
h_surfp = &(RoomSurf[h_surf]);
h_elemp = h_surfp->elemp + h_row * h_surfp->num_col + h_col;
ref_flux = h_surfp->reflectance * inc_flux;
h_elemp->total += ref_flux; /* Update total flux */
h_elemp->unsent += ref_flux; /* Update unsent flux */
}
s_elemp->unsent = 0.0; /* Res